import 'package:animated_toggle_switch/animated_toggle_switch.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_nb_net/flutter_net.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:tracker/common/log/x_logger.dart';
import 'package:tracker/common/model/base_resp.dart';
import 'package:tracker/common/model/command_setting_resp.dart';
import 'package:tracker/pages/home/home/model/home_device_info_resp.dart';
import 'package:tracker/pages/home/sound/model/sound_list_resp.dart';
import 'package:tracker/provider/global_provider.dart';
import 'package:tracker/provider/global_state_provider.dart';
import 'package:tracker/router/router_manager.dart';
import 'package:tracker/theme/app_theme.dart';
import 'package:tracker/utils/color_utils.dart';
import 'package:tracker/utils/toast_utils.dart';
import 'package:material_dialogs/material_dialogs.dart';
import 'package:material_dialogs/shared/types.dart';

/// 声音报警页面
class SoundPage extends ConsumerStatefulWidget {
  const SoundPage({super.key});

  @override
  ConsumerState<SoundPage> createState() => _SoundPageState();
}

class _SoundPageState extends ConsumerState<SoundPage> {
  bool showLoading = true;
  int pageNum = 1;
  List<SoundData> soundList = <SoundData>[];
  late EasyRefreshController _refreshController;
  final player = AudioPlayer();
  int switchValue = 0;

  /// 声音报警开关
  int soundValue = 0;

  /// 声音报警菊花
  bool soundLoading = false;

  _buildLoading() {
    return Center(
      child: CircularProgressIndicator(
        color: AppTheme.themeConfig.primaryColor,
      ),
    );
  }

  Widget _buildList() {
    if (soundList.isEmpty) {
      return Center(
        child: Text(
          '暂无声音报警',
          style: TextStyle(
            fontSize: 16,
            color: AppTheme.themeConfig.infoTextColor,
          ),
        ),
      );
    }
    return ListView.builder(
      itemCount: soundList.length + 1,
      itemBuilder: (context, index) {
        // 最后一项时，返回固定高度的空白widget
        if (index == soundList.length) {
          return Container(
            height: 40,
          );
        }
        return _buildCell(index);
      },
    );
  }

  _buildIcon(int index) {
    SoundData sound = soundList[index];
    if (sound.messageType == 'manual') {
      if (sound.isPlay) {
        return const Image(
          image: AssetImage('assets/images/sound/voice_play.gif'),
          width: 30,
          height: 30,
        );
      }
      return const Image(
        image: AssetImage('assets/images/sound/voice_icon.png'),
        width: 30,
        height: 30,
      );
    } else {
      return const Image(
        image: AssetImage('assets/images/sound/circle.png'),
        width: 30,
        height: 30,
      );
    }
  }

  _getSoundTypeStr(String messageType) {
    if (messageType == 'manual') {
      return ' 声音报警确认';
    } else {
      return ' 声音报警';
    }
  }

  /// 点击cell
  _onCellClick(int index) async {
    SoundData sound = soundList[index];

    if (sound.messageType != 'manual') {
      return;
    }
    int playIndex = -1;
    if (player.state == PlayerState.playing) {
      // 停止播放
      player.stop();
      // 查找出正在播放的项，并修改状态
      for (int i = 0; i < soundList.length; i++) {
        SoundData item = soundList[i];
        if (item.isPlay) {
          playIndex = i;
          item.isPlay = false;
          setState(() {});
          break;
        }
      }
      return;
    }
    // 如果是当前项，则暂停播放即可，流程结束
    if (index == playIndex) {
      return;
    }

    // 开始播放声音
    XLogger.info('开始播放声音 ${sound.url}');
    ToastUtils.showLoading();
    await player.play(UrlSource(sound.url!));
    ToastUtils.dismissLoading();
    sound.isPlay = true;
    setState(() {});

    // 更新已读状态
    _markRead(index);
  }

  /// 设为已读
  _markRead(int index) async {
    SoundData sound = soundList[index];
    if (sound.read!) {
      return;
    }
    final queryParams = {
      'id': sound.id,
    };
    final res = await post<BaseResp, BaseResp>('/sound/markRead', data: queryParams, decodeType: BaseResp());
    res.when(success: (resp) {
      if (resp.code == 200) {
        sound.read = true;
        setState(() {});
      }
    }, failure: (String msg, int code) {
      XLogger.error('更新已读状态失败 code: $code msg: $msg');
    });
  }

  _buildCell(int index) {
    SoundData sound = soundList[index];
    // 设备信息cell
    return GestureDetector(
      onTap: () async {
        _onCellClick(index);
      },
      child: Container(
        height: 60,
        margin: const EdgeInsets.only(left: 20, right: 20, top: 20),
        padding: const EdgeInsets.only(
          left: 12,
          right: 12,
        ),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(8),
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            // 播放图标
            _buildIcon(index),
            const SizedBox(
              width: 8,
            ),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Row(
                    children: [
                      Text(
                        sound.title ?? '',
                        style: TextStyle(
                          fontSize: 16,
                          color: AppTheme.themeConfig.primaryTextColor,
                        ),
                      ),
                    ],
                  ),
                  Row(
                    children: [
                      Text(
                        sound.createTime ?? '',
                        style: TextStyle(
                          fontSize: 14,
                          color: AppTheme.themeConfig.primaryTextColor,
                        ),
                      ),
                    ],
                  )
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// 构建底部按钮
  _buildBottomButton() {
    // 屏幕宽度的一半-40
    final double halfWidth = MediaQuery.of(context).size.width / 2;
    return Positioned(
      bottom: 20,
      left: 40,
      right: 40,
      child: Container(
        child: AnimatedToggleSwitch<int>.size(
          current: soundValue,
          values: const [1, 0],
          // onChanged: (i) => {
          //   // 弹窗提示
          //   if (i == 1) {
          //     _showSoundAlarmOnDialog()
          //   } else {
          //     _showSoundAlarmOffDialog()
          //   },
          //   // setState(() => soundValue = i)
          // },
          onTap: (i) {
            XLogger.info('点击了 ${i.tapped?.index}');
            if (i.tapped?.index == 0) {
              _showSoundAlarmOnDialog();
            } else {
              _showSoundAlarmOffDialog();
            }
          },
          style: ToggleStyle(
            backgroundColor: ColorUtils.hexToColor('#ffffff'),
            indicatorColor: AppTheme.themeConfig.primaryColor,
            borderColor: AppTheme.themeConfig.infoTextColor,
            borderRadius: BorderRadius.circular(12.0),
            indicatorBorderRadius: BorderRadius.zero,
          ),
          selectedIconScale: 1.0,
          borderWidth: 1.0,
          // spacing: 2.0,
          indicatorSize: Size.fromWidth(halfWidth),
          customIconBuilder: (context, local, global) {
            final text = const ['打开声音报警', '关闭声音报警'][local.index];
            return Center(
                child: Text(text,
                    style:
                        TextStyle(fontSize: 16, color: Color.lerp(Colors.black, Colors.white, local.animationValue))));
          },
          loading: soundLoading,
        ),
      ),
    );
  }

  /// 使用条款弹窗
  _showTermsDialog() {
    final globalConfig = ref.watch(globalStateProvider).globalConfig!;
    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text(
              '声音报警使用条款',
              style: TextStyle(
                fontSize: 18,
                color: AppTheme.themeConfig.primaryTextColor,
              ),
            ),
            content: Text(
              globalConfig.soundAlertTermsOfUse ?? '',
              style: TextStyle(
                fontSize: 14,
                color: AppTheme.themeConfig.primaryTextColor,
              ),
            ),
            actions: [
              // 取消
              TextButton(
                onPressed: () {
                  Navigator.pop(context);
                  Navigator.pop(context);
                },
                child: Text(
                  '不同意',
                  style: TextStyle(
                    fontSize: 16,
                    color: AppTheme.themeConfig.primaryTextColor,
                  ),
                ),
              ),
              TextButton(
                onPressed: () {
                  Navigator.pop(context);
                  // 获取声音列表
                  _fetchSoundList(true);
                  _loadUserAlarmSetting();
                },
                child: Text(
                  '同意',
                  style: TextStyle(
                    fontSize: 16,
                    color: AppTheme.themeConfig.primaryColor,
                  ),
                ),
              ),
            ],
          );
        });
  }

  _fetchSoundList(bool isRefresh) async {
    DeviceInfoVO deviceInfo = ref.read(deviceInfoProvider);
    // 假设备处理
    if (deviceInfo.isNineDevice == true) {
      _refreshController.finishRefresh();
      soundList.clear();
      setState(() {
        showLoading = false;
      });
      return;
    }
    final queryParams = {
      'pageNum': pageNum,
      'pageSize': 10,
      'imei': deviceInfo.imei,
    };
    final res = await post<SoundListResp, SoundListResp>('/sound/list', data: queryParams, decodeType: SoundListResp());
    res.when(success: (resp) {
      if (resp.code == 200) {
        if (isRefresh) {
          soundList.clear();
          soundList.addAll(resp.rows!);
          // 判断是否还有更多数据
          if (resp.rows == null || resp.rows!.isEmpty || resp.rows!.length < 10) {
            _refreshController.finishLoad(IndicatorResult.noMore);
          } else {
            _refreshController.finishRefresh();
          }
          pageNum++;
        } else {
          if (resp.rows == null || resp.rows!.isEmpty) {
            _refreshController.finishLoad(IndicatorResult.noMore);
          } else {
            pageNum++;
            soundList.addAll(resp.rows!);
            _refreshController.finishLoad();
          }
        }
      } else {
        ToastUtils.showToast(resp.msg ?? '获取声音报警失败');
      }
      setState(() {
        showLoading = false;
      });
    }, failure: (String msg, int code) {
      XLogger.error('获取声音报警失败 code: $code msg: $msg');
    });
  }

  /// 声音报警开关弹窗
  _showAlarmSwitchDialog() async {}

  // 查询声音报警开关状态
  _loadUserAlarmSetting() async {
    DeviceInfoVO deviceInfo = ref.read(deviceInfoProvider);
    final queryParams = {
      'imei': deviceInfo.imei,
      'cmdCode': 'db',
    };
    ToastUtils.showLoading();
    final res = await post<CommandSettingResp, CommandSettingResp>('/command/getSetting',
        data: queryParams, decodeType: CommandSettingResp());
    res.when(success: (resp) {
      ToastUtils.dismissLoading();
      if (resp.code == 200) {
        CommandSettingData? data = resp.data;
        if (data != null) {
          // 解析指令内容：db,0
          List<String> contentList = data.cmdContent!.split(',');
          if (contentList.length == 2) {
            soundValue = int.parse(contentList[1]);
            setState(() {});
          }
        }
      } else {
        ToastUtils.showToast(resp.msg ?? '获取声音报警开关失败');
      }
    }, failure: (String msg, int code) {
      ToastUtils.dismissLoading();
      XLogger.error('获取声音报警开关失败 code: $code msg: $msg');
    });
  }

  /// 构建打开声音报警开关弹窗
  _showSoundAlarmOnDialog() {
    return Dialogs.bottomMaterialDialog(
        context: context,
        customView: StatefulBuilder(builder: (context, newSetState) {
          return Container(
            padding: const EdgeInsets.only(left: 20, right: 20, top: 20),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '打开声音报警',
                  style: TextStyle(
                    fontSize: 18,
                    color: AppTheme.themeConfig.primaryTextColor,
                  ),
                ),
                const SizedBox(
                  height: 20,
                ),
                Row(
                  children: [
                    // 提示语
                    Expanded(
                      child: Text(
                        '设备周围有异响时会上报一次声音报警，请您及时关注报警提示，避免财物损失。\n打开声音报警时设备耗电，电池续航减少，请您注意关注设备电量及时充电。',
                        style: TextStyle(
                          fontSize: 16,
                          color: AppTheme.themeConfig.secondaryTextColor,
                        ),
                      ),
                    ),
                  ],
                ),
              ],
            ),
          );
        }),
        customViewPosition: CustomViewPosition.BEFORE_TITLE,
        actions: [
          TextButton(
            onPressed: () {
              Navigator.pop(context);
            },
            child: const Text(
              '取消',
              style: TextStyle(color: Colors.grey, fontSize: 15),
            ),
          ),
          TextButton(
            onPressed: () {
              _sendCommand(1);
            },
            child: Text(
              '发送指令',
              style: TextStyle(color: AppTheme.themeConfig.primaryColor, fontSize: 15),
            ),
          ),
        ]);
  }

  /// 构建关闭声音报警开关弹窗
  _showSoundAlarmOffDialog() {
    return Dialogs.bottomMaterialDialog(
        context: context,
        customView: StatefulBuilder(builder: (context, newSetState) {
          return Container(
            padding: const EdgeInsets.only(left: 20, right: 20, top: 20),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '关闭声音报警',
                  style: TextStyle(
                    fontSize: 18,
                    color: AppTheme.themeConfig.primaryTextColor,
                  ),
                ),
                const SizedBox(
                  height: 20,
                ),
                Row(
                  children: [
                    // 提示语
                    Expanded(
                      child: Text(
                        '关闭之后设备不再上报声音报警消息。',
                        style: TextStyle(
                          fontSize: 16,
                          color: AppTheme.themeConfig.secondaryTextColor,
                        ),
                      ),
                    ),
                  ],
                ),
              ],
            ),
          );
        }),
        customViewPosition: CustomViewPosition.BEFORE_TITLE,
        actions: [
          TextButton(
            onPressed: () {
              Navigator.pop(context);
            },
            child: const Text(
              '取消',
              style: TextStyle(color: Colors.grey, fontSize: 15),
            ),
          ),
          TextButton(
            onPressed: () {
              _sendCommand(0);
            },
            child: Text(
              '发送指令',
              style: TextStyle(color: AppTheme.themeConfig.primaryColor, fontSize: 15),
            ),
          ),
        ]);
  }

  /// 发送声音报警开关指令
  _sendCommand(int value) async {
    DeviceInfoVO deviceInfo = ref.read(deviceInfoProvider);
    Navigator.pop(context);
    final postData = {
      'imei': deviceInfo.imei,
      'cmdCode': 'db',
      'content': 'db,$value',
    };
    ToastUtils.showLoading(maskType: EasyLoadingMaskType.clear);
    final res = await post<BaseResp, BaseResp>('/command/send', data: postData, decodeType: BaseResp());
    res.when(success: (resp) {
      ToastUtils.dismissLoading();
      if (resp.code == 200) {
        ToastUtils.showToast('发送成功');
        setState(() {
          soundValue = value;
        });
      } else {
        ToastUtils.showToast(resp.msg ?? '发送失败');
      }
    }, failure: (String msg, int code) {
      XLogger.error('发送声音报警开关指令失败 code: $code msg: $msg');
    });
  }

  /// 声音报警确认弹窗
  _showAlarmConfirmDialog() {
    final globalConfig = ref.watch(globalStateProvider).globalConfig!;
    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            backgroundColor: Colors.white,
            title: Text(
              '声音报警确认',
              style: TextStyle(
                fontSize: 18,
                color: AppTheme.themeConfig.primaryTextColor,
              ),
            ),
            content: Text(
              globalConfig.soundAlertCommandTip ?? '',
              style: TextStyle(
                fontSize: 14,
                color: AppTheme.themeConfig.primaryTextColor,
              ),
            ),
            actions: [
              // 取消
              TextButton(
                onPressed: () {
                  Navigator.pop(context);
                },
                child: Text(
                  '取消',
                  style: TextStyle(
                    fontSize: 16,
                    color: AppTheme.themeConfig.primaryTextColor,
                  ),
                ),
              ),
              TextButton(
                onPressed: () {
                  Navigator.pop(context);
                  // 发送声音报警确认指令
                  _sendAlarmConfirmCommand();
                },
                child: Text(
                  '确认',
                  style: TextStyle(
                    fontSize: 16,
                    color: AppTheme.themeConfig.primaryColor,
                  ),
                ),
              ),
            ],
          );
        });
  }

  /// 发送声音报警确认指令
  _sendAlarmConfirmCommand() async {
    DeviceInfoVO deviceInfo = ref.read(deviceInfoProvider);
    final postData = {
      'imei': deviceInfo.imei,
    };
    ToastUtils.showLoading(status: '正在下发...');
    final res = await post<BaseResp, BaseResp>('/sound/manualRecording', data: postData, decodeType: BaseResp());
    res.when(success: (resp) {
      ToastUtils.dismissLoading();
      // 弹窗显示结果
      showDialog(
          context: context,
          builder: (context) {
            return AlertDialog(
              title: Text(
                '声音报警确认',
                style: TextStyle(
                  fontSize: 18,
                  color: AppTheme.themeConfig.primaryTextColor,
                ),
              ),
              content: Text(
                resp.msg ?? '',
                style: TextStyle(
                  fontSize: 14,
                  color: AppTheme.themeConfig.primaryTextColor,
                ),
              ),
              actions: [
                TextButton(
                  onPressed: () {
                    Navigator.pop(context);
                  },
                  child: Text(
                    '好的',
                    style: TextStyle(
                      fontSize: 16,
                      color: AppTheme.themeConfig.primaryColor,
                    ),
                  ),
                ),
              ],
            );
          });
    }, failure: (String msg, int code) {
      XLogger.error('发送声音报警确认指令失败 code: $code msg: $msg');
    });
  }

  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      // 在build完成后回调
      // _showTermsDialog();
      _loadUserAlarmSetting();
      _fetchSoundList(true);
      player.onPlayerStateChanged.listen((event) {
        // 开始播放
        if (event == PlayerState.playing) {
          XLogger.info('开始播放');
        }
        if (event == PlayerState.completed) {
          // 播放完成
          XLogger.info('播放完成');
          for (int i = 0; i < soundList.length; i++) {
            SoundData item = soundList[i];
            if (item.isPlay) {
              item.isPlay = false;
              setState(() {});
              break;
            }
          }
        }
      });
      player.onLog.listen((event) {
        XLogger.info('播放日志 $event');
      });
    });
    super.initState();
    _refreshController = EasyRefreshController(
      controlFinishLoad: true,
      controlFinishRefresh: true,
    );
  }

  @override
  void dispose() async {
    super.dispose();
    await player.dispose();
    _refreshController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('声音报警', style: TextStyle(fontSize: 18),),
          centerTitle: true,
          backgroundColor: AppTheme.themeConfig.navBarColor,
          foregroundColor: AppTheme.themeConfig.primaryColor,
          leading: IconButton(
            onPressed: () {
              Navigator.pop(context);
            },
            icon: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(' <返回'),
              ],
            ),
          ),
        ),
        backgroundColor: ColorUtils.hexToColor('#f5f5f5'),
        body: Stack(
          children: [
            Positioned(
              bottom: 90,
              left: 0,
              right: 0,
              top: 0,
              child: EasyRefresh(
                  controller: _refreshController,
                  onRefresh: () async {
                    pageNum = 1;
                    await _fetchSoundList(true);
                    _refreshController.finishRefresh();
                  },
                  onLoad: () async {
                    await _fetchSoundList(false);
                  },
                  child: showLoading ? _buildLoading() : _buildList()),
            ),

            /// 底部开关按钮
            _buildBottomButton(),
          ],
        ));
  }
}
